package com.mobilezu.mobile.pushserver.xmpp;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.mobilezu.mobile.pushserver.util.Config;
import com.mobilezu.mobile.pushserver.util.Constants;
import com.mobilezu.mobile.pushserver.xmpp.session.SessionManager;


public class XmppServer {

	private static final Log log = LogFactory.getLog(XmppServer.class);
	private static XmppServer instance;
	private ApplicationContext context;
	private String serverName;
	private boolean shuttingDown;

	public static XmppServer getInstance() {
		if (instance == null) {
			synchronized (XmppServer.class) {
				instance = new XmppServer();
			}
		}
		return instance;
	}

	
	public XmppServer() {
		if (instance != null) {
			throw new IllegalStateException("A server is already running");
		}
		instance = this;
		start();
	}

	
	public void start() {
		try {
			if (isStandAlone()) {
				Runtime.getRuntime().addShutdownHook(new ShutdownHookThread());
			}
			
			serverName = Config.getString("xmpp.domain", "127.0.0.1")
					.toLowerCase();
			
			//context = new ClassPathXmlApplicationContext("applicationContext.xml");
			context=ApplicationContextRegister.getContext();
			
			log.info("Spring Configuration loaded.");
			log.info(Constants.server_name_version);

		} catch (Exception e) {
			e.printStackTrace();
			shutdownServer();
		}
	}

	/**
	 * ֹͣServer
	 */
	public void stop() {
		shutdownServer();
		Thread shutdownThread = new ShutdownThread();
		shutdownThread.setDaemon(true);
		shutdownThread.start();
	}

	/**
	 * ��bean name��ȡbean
	 * 
	 * @param beanName
	 * @return a Srping bean
	 */
	public Object getBean(String beanName) {
		return context.getBean(beanName);
	}

	/**
	 * ��ȡserverName
	 * 
	 * @return the server name
	 */
	public String getServerName() {
		return serverName;
	}

	/**
	 * �жϷ������Ƿ����ڹر�
	 * 
	 * @return true if the server is being down, false otherwise.
	 */
	public boolean isShuttingDown() {
		return shuttingDown;
	}

	/**
	 * �жϷ������Ƿ����Զ���ģʽ���е�
	 * 
	 * @return true if the server is running in standalone mode, false
	 *         otherwise.
	 */
	public boolean isStandAlone() {
		boolean standalone;
		try {
			standalone = Class
					.forName("org.shmtu.lab.pushserver.starter.ServerStarter") != null;
		} catch (ClassNotFoundException e) {
			standalone = false;
		}
		return standalone;
	}

	private void shutdownServer() {
		shuttingDown = true;
		// Close all connections
		SessionManager.getInstance().closeAllSessions();
		log.info("XmppServer stopped");
	}

	private class ShutdownHookThread extends Thread {
		public void run() {
			shutdownServer();
			log.info("Server halted");
			System.err.println("Server halted");
		}
	}

	private class ShutdownThread extends Thread {
		public void run() {
			try {
				Thread.sleep(5000);
				System.exit(0);
			} catch (InterruptedException e) {
				// Ignore
			}
		}
	}

}
